#include "CMeleeEnemy.h"
#include "MathLib.h"
#include "tinyxml/tinyxml.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_DirectInput.h"
#include "VIN_ObjectManager.h"
#include "VIN_SoundManager.h"
#include "VIN_EventSystem.h"
#include "CPlayer.h"
#include "CHubState.h"

CMeleeEnemy::CMeleeEnemy()
{
	SetAlive(true);
	SetPassive(true);;
	SetDistanceToPlayer(VIN_Vector2D(0.0f, 0.0f));
	SetHP(1000);
	SetPower(1);
	Load("resource/XML/thug_animation.xml");
	SetType(OBJ_ENEMY);
	CurrAnimation = 1;
	punching = false;
	bucket = 0;
	SetAlive(true);
	VIN_EventSystem::GetInstance()->ResgisterClient("KillAll",this);
	flickbucket = 0.0f;
	flicker = true;
	counter = 0;
	m_bIsPaid = false;
	xspeed = 100;
	yspeed = 20;
	scale = 1.0f;
	

}

CMeleeEnemy::CMeleeEnemy(int i)
{
	SetAlive(true);
	SetPassive(true);;
	SetDistanceToPlayer(VIN_Vector2D(0.0f, 0.0f));
	SetHP(1500);
	SetPower(2);
	Load("resource/XML/thug2_animation.xml");
	SetType(OBJ_ENEMY);
	CurrAnimation = 1;
	punching = false;
	bucket = 0;
	SetAlive(true);
	VIN_EventSystem::GetInstance()->ResgisterClient("KillAll",this);
	flickbucket = 0.0f;
	flicker = true;
	counter = 0;
	m_bIsPaid = false;
	scale = 1.2f;
	xspeed = 50;
	yspeed = 5;
}

CMeleeEnemy::~CMeleeEnemy()
{
	VIN_EventSystem::GetInstance()->UnregisterClient("KillAll",this);
}
RECT CMeleeEnemy::GetAttackRect()
{
	RECT temp;
	if(CurrAnimation < (int)vAnimation.size())
	{
		temp.left  = (int)GetPosX() + vAnimation[CurrAnimation].GetAttackFrame().left ;
		temp.right = (int)GetPosX() + vAnimation[CurrAnimation].GetAttackFrame().right;
		temp.top   = (int)GetPosY() + vAnimation[CurrAnimation].GetAttackFrame().top;
		temp.bottom= (int)GetPosY() + vAnimation[CurrAnimation].GetAttackFrame().bottom;
		if(flip)
		{
			temp.left = (int)GetPosX() - vAnimation[CurrAnimation].GetAttackFrame().right ;
			temp.right =(int)GetPosX() - vAnimation[CurrAnimation].GetAttackFrame().left;
		}
		return temp;
	}
	else
	{
		SetRect(&temp,0,0,0,0);
		return temp;
	}

}
RECT CMeleeEnemy::GetHealthRect()
{
	RECT temp;
	if(CurrAnimation < (int)vAnimation.size())
	{
		temp.left  = (int)GetPosX() + vAnimation[CurrAnimation].GetHealthFrame().left ;
		temp.right = (int)GetPosX() + vAnimation[CurrAnimation].GetHealthFrame().right;
		temp.top   = (int)GetPosY() + vAnimation[CurrAnimation].GetHealthFrame().top;
		temp.bottom= (int)GetPosY() + vAnimation[CurrAnimation].GetHealthFrame().bottom;
		return temp;
	}
	else
	{
		SetRect(&temp,0,0,0,0);
		return temp;
	}

}
void CMeleeEnemy::HandleEVent(CEvent* pEvent)
{
	if(pEvent->GetEventID() == "KillAll")
	{
		SetHP(GetHP() - 100);
	}
}
bool CMeleeEnemy::CheckCollision(IBaseInterface *pBase)
{
	
	CPlayer* player = (CPlayer*)pBase;
	RECT temp;
	if(pBase->GetType() == OBJ_PLAYER)
	{
		if(IntersectRect(&temp,&GetAttackRect(),&player->GetHealthRect()))
		{
			VIN_SoundManager::GetInstance()->PlayPunch();

			int test = GetPower();
			float DuraMod = .70f;
			if( CHubState::GetInstance()->GetPlayer()->GetDurability() == 1 )
			{
				DuraMod = .75f;
			}
			else if(CHubState::GetInstance()->GetPlayer()->GetDurability() == 2 )
			{
				DuraMod = .80f;
			}
			else if( CHubState::GetInstance()->GetPlayer()->GetDurability() == 3 )
			{
				DuraMod = .90f;
			}
			else if( CHubState::GetInstance()->GetPlayer()->GetDurability() == 4 )
			{
				DuraMod = .95f;
			}
			else if( CHubState::GetInstance()->GetPlayer()->GetDurability() >= 5 )
			{
				DuraMod = 1.0f;
			}
			

			CHubState::GetInstance()->GetPlayer()->SetHP((CHubState::GetInstance()->GetPlayer()->GetHP() - GetPower()) + ( GetPower() * DuraMod));
			
			

			if(CHubState::GetInstance()->GetPlayer()->IsPissed() == false)
				CHubState::GetInstance()->GetPlayer()->SetRageAmnt(CHubState::GetInstance()->GetPlayer()->GetRageAmt() + 2.0f);			
		}

		

	}
	
	return false;
}

void CMeleeEnemy::Attack()
{
	// TODO: Play an animation and if the collision rect hits the player's hitbox
	// subtract the player's health by GetPower()
	// play punch sounds
	CurrAnimation = rand() % 2 + 2;
	vAnimation[CurrAnimation].SetCurFrame(0);


    VIN_SoundManager::GetInstance()->PlayWoosh();
}
void CMeleeEnemy::HurtMe()
{
	float CombatModifier = .5f;
	if( CHubState::GetInstance()->GetPlayer()->GetCombat() == 1 )
	{
		CombatModifier = 1.0f;
	}
	else if( CHubState::GetInstance()->GetPlayer()->GetCombat() == 2 )
	{
		CombatModifier = 1.5f;
	}
	else if( CHubState::GetInstance()->GetPlayer()->GetCombat() == 3 )
	{
		CombatModifier = 2.0f;
	}
	else if( CHubState::GetInstance()->GetPlayer()->GetCombat() == 4 )
	{
		CombatModifier = 2.5f;
	}
	else if( CHubState::GetInstance()->GetPlayer()->GetCombat() >= 5 )
	{
		CombatModifier = 3.0f;
	}

	int DMG = (rand() % 5 + 1);
	float DMGModifier = DMG + ( DMG * CombatModifier );
	SetHP( GetHP() - DMGModifier );

}
void CMeleeEnemy::Update( float fElapsedTime)
{
	SetDistanceToPlayer(VIN_Vector2D(GetPosX() - CHubState::GetInstance()->GetPlayer()->GetPosX(), GetPosY() - CHubState::GetInstance()->GetPlayer()->GetPosY()));
	vAnimation[CurrAnimation].Update(fElapsedTime);
	vAnimation[CurrAnimation].Play();
	static float attacktimer = 0.00f;
	if(GetHP() <= 0)
	{
		SetHP(0);
		CurrAnimation = 4;
		SetVelX(0);
		SetVelY(0);
		if(vAnimation[CurrAnimation].GetCurFrame() >= vAnimation[CurrAnimation].GetMaxFrames() - 1)
		{
			if(vAnimation[CurrAnimation].Playing())
				vAnimation[CurrAnimation].Stop();
			bucket += fElapsedTime;
			flickbucket+= fElapsedTime;
			if(flickbucket >= 0.12f)
			{
				flicker = !flicker;
				flickbucket = 0;
			}
			if(bucket >= 1.0f)
			{
				bucket = 0;
				flicker = true;
				SetAlive(false);
			}
		}
	}


	else if(GetDistanceToPlayer().LengthOfVector(GetDistanceToPlayer())  < 70.0f)
	{
		SetVelX(0.0f);
		SetVelY(0.0f);
		if(!punching)
		{
			CurrAnimation = 0;
		}
		attacktimer += fElapsedTime;
		if(attacktimer >= .75f)
		{
			punching = true;
			Attack();

			attacktimer = 0.0f;
		}
	}

	else
	{
		punching = false;
		//attacktimer = 0.0f;
		if(!punching)
		{
			CurrAnimation = 1;
		}
		if(GetPosX() > CHubState::GetInstance()->GetPlayer()->GetPosX())
		{
			SetVelX(-xspeed);
			flip = true;
		}
		else
		{
			SetVelX(xspeed);
			flip = false;
		}
		if(GetPosY() > CHubState::GetInstance()->GetPlayer()->GetPosY())
		{
			SetVelY(-yspeed);
		}
		else
		{
			SetVelY(yspeed);
		}
	}

	if(GetHP() != 0)
	{
		SetPosX(GetPosX() + (GetVelX() * fElapsedTime));
		SetPosY(GetPosY() + (GetVelY() * fElapsedTime));
	}
	if( GetHP() <= 0 && m_bIsPaid == false )
	{
		CHubState::GetInstance()->GetPlayer()->SetCash( CHubState::GetInstance()->GetPlayer()->GetCash() + 50);
		m_bIsPaid = true;
	}

	SetPosX(GetPosX() + (GetVelX() * fElapsedTime));
	SetPosY(GetPosY() + (GetVelY() * fElapsedTime));
}
void CMeleeEnemy::Render(void)
{
	CSGD_TextureManager* pTM  = CSGD_TextureManager::GetInstance();
	CSGD_Direct3D* d3d  = CSGD_Direct3D::GetInstance();
	//char hp[100];
	//sprintf_s(hp, sizeof(hp), "HP: %d", GetHP() );
	if(flicker)
		vAnimation[CurrAnimation].Render(GetPosX() , GetPosY() , flip, scale);

	//d3d->DrawTextA(hp,(int)GetPosX(),(int)GetPosY()- GetHeight() ,0,0,100);

	d3d->GetSprite()->Flush();
	
}

bool CMeleeEnemy::Load( const char* AnimInfo)
{
	int tempID;

	TiXmlDocument doc;

	if(doc.LoadFile(AnimInfo) == false)
		return false;

	TiXmlElement* Root = doc.RootElement();
	if(Root == NULL)
		return false;

	TiXmlElement* NumAnim = Root->FirstChildElement("xNumOfAnim");
	int count = atoi(NumAnim->GetText());

	TiXmlElement* ImageFile = Root->FirstChildElement("xImageFile");
	if(ImageFile)
	{
		tempID = CSGD_TextureManager::GetInstance()->LoadTexture(ImageFile->GetText());
	}

	TiXmlElement* xAnimation  = Root->FirstChildElement("xAnimation");

	while(xAnimation)
	{
		CAnimation a;

		TiXmlElement* NumFrame = xAnimation->FirstChildElement("xNumOfFrames");
		int fcount = atoi(NumFrame->GetText());

		TiXmlElement* looping = xAnimation->FirstChildElement("xLooping");
		a.SetIsLooping((bool)(atoi(looping->GetText())));

		TiXmlElement* AnimSpd = xAnimation->FirstChildElement("xAnimSpd");
		a.SetSpeed((float)( atoi(AnimSpd->GetText())));

		TiXmlElement* xFrame = xAnimation->FirstChildElement("xFrame");

		Frame temp;
		temp.fTime = 0;
		temp.ptAnchor.x = 0;
		temp.ptAnchor.y = 0;

		SetRect(&temp.rAttack,0,0,0,0);
		SetRect(&temp.rCollision,0,0,0,0);
		SetRect(&temp.rRender,0,0,0,0);

		temp.ptAnchor.x = 0;
		temp.ptAnchor.y = 0;


		while(xFrame)
		{
			TiXmlElement* xTime = xFrame->FirstChildElement("xTime");
			if(xTime)
			{
				temp.fTime =(float)( atoi(xTime->GetText()) );
			}
			TiXmlElement* FrameType = xFrame->FirstChildElement("xFrameType");
			if(FrameType)
			{
				TiXmlElement* RenderFrame = FrameType->FirstChildElement("xRenderFrame");
				if(RenderFrame)
				{
					TiXmlElement* RenderFrameX = RenderFrame->FirstChildElement("xRenderFrameX");
					if(RenderFrameX)
						temp.rRender.left =  atoi(RenderFrameX->GetText());

					TiXmlElement* RenderFrameY = RenderFrame->FirstChildElement("xRenderFrameY");
					if(RenderFrameY)
						temp.rRender.top = atoi(RenderFrameY->GetText());

					TiXmlElement* RenderFrameW = RenderFrame->FirstChildElement("xRenderFrameW");
					if(RenderFrameW)
					{
						temp.rRender.right = atoi(RenderFrameW->GetText());
						temp.rRender.right += temp.rRender.left;
					}

					TiXmlElement* RenderFrameH = RenderFrame->FirstChildElement("xRenderFrameH");
					if(RenderFrameH)
					{
						temp.rRender.bottom = atoi(RenderFrameH->GetText());
						temp.rRender.bottom += temp.rRender.top;
					}
				}

				TiXmlElement* CollisionFrame = FrameType->FirstChildElement("xCollisionFrame");
				if(CollisionFrame)
				{
					TiXmlElement* CollisionFrameX = CollisionFrame->FirstChildElement("xCollisionFrameX");
					if(CollisionFrameX)
						temp.rCollision.left = atoi(CollisionFrameX->GetText());

					TiXmlElement* CollisionFrameY = CollisionFrame->FirstChildElement("xCollisionFrameY");
					if(CollisionFrameY)
						temp.rCollision.top = atoi(CollisionFrameY->GetText());

					TiXmlElement* CollisionFrameW = CollisionFrame->FirstChildElement("xCollisionFrameW");
					if(CollisionFrameW)
						temp.rCollision.right = atoi(CollisionFrameW->GetText());

					TiXmlElement* CollisionFrameH = CollisionFrame->FirstChildElement("xCollsionFrameH");
					if(CollisionFrameH)
						temp.rCollision.bottom = atoi(CollisionFrameH->GetText());
				}

				TiXmlElement* AttackFrame = FrameType->FirstChildElement("xAttackFrame");
				if(AttackFrame)
				{
					TiXmlElement* AttackFrameX = AttackFrame->FirstChildElement("xAttackFrameX");
					if(AttackFrameX)
						temp.rAttack.left = atoi(AttackFrameX->GetText());

					TiXmlElement* AttackFrameY = AttackFrame->FirstChildElement("xAttackFrameY");
					if(AttackFrameY)
						temp.rAttack.top = atoi(AttackFrameY->GetText());

					TiXmlElement* AttackFrameW = AttackFrame->FirstChildElement("xAttackFrameW");
					if(AttackFrameW)
						temp.rAttack.right = atoi(AttackFrameW->GetText());

					TiXmlElement* AttackFrameH = AttackFrame->FirstChildElement("xAttackFrameH");
					if(AttackFrameH)
						temp.rAttack.bottom = atoi(AttackFrameH->GetText());
				}

				TiXmlElement* AnchorPoint = FrameType->FirstChildElement("xAnchorPoint");
				if(AnchorPoint)
				{
					TiXmlElement* AnchorPointX = AnchorPoint->FirstChildElement("xAnchorPointX");
					if(AnchorPointX)
					{
						int ax = atoi(AnchorPointX->GetText());
						temp.ptAnchor.x =  ax - temp.rRender.left;
					}

					TiXmlElement* AnchorPointY = AnchorPoint->FirstChildElement("xAnchorPointY");
					if(AnchorPointY)
					{
						int ay = atoi(AnchorPointY->GetText());
						temp.ptAnchor.y = ay - temp.rRender.top;
					}
				}
			}
			a.SetTimeDelay(temp.fTime);

			temp.rAttack.right +=  temp.rAttack.left;
			temp.rAttack.bottom += temp.rAttack.top;
			temp.rAttack.left -= (temp.ptAnchor.x + temp.rRender.left);
			temp.rAttack.top -= (temp.ptAnchor.y + temp.rRender.top);
			temp.rAttack.right -= (temp.ptAnchor.x + temp.rRender.left);
			temp.rAttack.bottom -=(temp.ptAnchor.y + temp.rRender.top);



			temp.rCollision.right +=  temp.rCollision.left;
			temp.rCollision.bottom += temp.rCollision.top;
			temp.rCollision.left -= (temp.ptAnchor.x + temp.rRender.left);
			temp.rCollision.top -= (temp.ptAnchor.y + temp.rRender.top);
			temp.rCollision.right -= (temp.ptAnchor.x + temp.rRender.left);
			temp.rCollision.bottom -=(temp.ptAnchor.y + temp.rRender.top);


			a.addFrame(temp);
			xFrame = xFrame->NextSiblingElement("xFrame");
		}
		a.SetImageID(tempID);
		vAnimation.push_back(a);

		xAnimation = xAnimation->NextSiblingElement("xAnimation");



	}



	return true;

}

CMeleeEnemy::CMeleeEnemy( CMeleeEnemy& copy)
{

	this->SetPosX( copy.GetPosX() );
	this->SetPosY( copy.GetPosY() );
	this->SetVelX( copy.GetVelX() );
	this->SetHP( copy.GetHP() );
	this->SetPower(copy.GetPower());
	this->SetWidth( copy.GetWidth() );
	this->SetHeight( copy.GetHeight() );
	this->SetType( copy.GetType() );
	this->SetAlive( copy.GetAlive() );
	this->SetPassive( copy.GetPassive() );
	this->SetCurAnimation( 0 );
	punching = false;
	bucket = 0.0f;
	flickbucket = 0;
	this->scale = copy.scale;
	this->xspeed = copy.xspeed;
	this->yspeed = copy.yspeed;


	for( unsigned int i = 0; i < copy.vAnimation.size(); i++ )
	{
		CAnimation temp = copy.vAnimation[i];
		vAnimation.push_back(temp);
	}


}